#include <QDir>
#include <QTextStream>
#include <QMessageBox>
#include <QKeyEvent>

#include "WidgetBinds.h"
#include "ColorDialog.h"
#include "PressButtonDialog.h"
#include "ui_WidgetBinds.h"

WidgetBinds::WidgetBinds(QWidget *parent) :
        QWidget(parent),
        m_ui(new Ui::WidgetBinds)
{
    m_ui->setupUi(this);

    // Initialize values
    currentAction_ = say;
    m_ui->labSaveInfo->setText("");

    // Initialize some graphics components
    m_ui->comboSay->setEnabled(true);
    m_ui->lineEditSayText->setEnabled(true);
    m_ui->btnChooseColor->setEnabled(true);

    // Initialize Keys combo Box
    QDir dir;
    dir.cd(QCoreApplication::applicationDirPath());
    dir.cd("files");
    // First we read the key list
    QFile fileKeys(dir.filePath("possible_keys.txt"));
    if(fileKeys.exists()){
        fileKeys.open(QIODevice::ReadOnly | QIODevice::Text);
        QTextStream in(&fileKeys);
        QStringList strings;
        while(!in.atEnd()){
            strings.append(in.readLine());
        }
        keys = strings;

        // Initialize the key combo box with the keys
        m_ui->comboKey->addItems(strings);
    }

    // Initialize the key press button
    m_ui->btnKey->setText(m_ui->comboKey->currentText());

    // Then we read the actions list
    QFile fileActions(dir.filePath("possible_actions.txt"));
    if(fileActions.exists()){
        fileActions.open(QIODevice::ReadOnly | QIODevice::Text);
        QTextStream in(&fileActions);
        QString reader;  		// A String to read the line

        // A string list for each kind
        QStringList sayString;
        QStringList sellString;
        QStringList buyString;
        QStringList actString;
        QStringList evoString;
        QStringList adminString;
        QStringList misString;
        EnumActions action = say;

        while(!in.atEnd()){
            reader = in.readLine();
            // If enter in a new type of action
            if(reader[0] == '-'){
                reader.remove(0, 2);
                if(reader == "say commands")
                    action = say;
                else if(reader == "sell commands")
                    action = sell;
                else if(reader == "buy commands")
                    action = buy;
                else if(reader == "itemact commands")
                    action = act;
                else if(reader == "evolution commands")
                    action = evo;
                else if(reader == "admin commands")
                    action = admin;
                else if(reader == "miscellaneous commands")
                    action = mis;
            }else{  // Save in the current type of action

                switch(action){
                case say: sayString.append(reader);
                    break;
                case sell: sellString.append(reader);
                    break;
                case buy: buyString.append(reader);
                    break;
                case act: actString.append(reader);
                    break;
                case evo: evoString.append(reader);
                    break;
                case admin: adminString.append(reader);
                    break;
                case mis: misString.append(reader);
                    break;
                }
            }
        }
        m_ui->comboSay->addItems(sayString);
        m_ui->comboSell->addItems(sellString);
        m_ui->comboBuy->addItems(buyString);
        m_ui->comboActiveItem->addItems(actString);
        m_ui->comboEvolution->addItems(evoString);
        m_ui->comboAdmin->addItems(adminString);
        m_ui->comboMis->addItems(misString);
    }

}

WidgetBinds::~WidgetBinds()
{
    delete m_ui;
}

// ********************* Public Methods ***************
void WidgetBinds::setBinds(BindList binds){
    binds_.clearList();
    binds_.copy(binds);
    on_comboKey_currentIndexChanged(m_ui->comboKey->currentText());
}

void WidgetBinds::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}


// ***************** Private Methods ******************

void WidgetBinds::saveBinds(){

    // First, get the path
    QDir dir;
    dir.cd(dir.homePath());
    dir.cd(".qtrembinds");
    QFile filePath(dir.filePath("current_path.txt"));
    filePath.open(QIODevice::ReadOnly | QIODevice::Text);
    QTextStream in(&filePath);
    QString line = in.readLine();

    // go to the path
    dir.cd(line);
    dir.cd("base");
    filePath.close();
    if(dir.exists("autogen_backup.cfg")){
        dir.remove("autogen_backup.cfg");
    }

    // Open the files
    QFile fileAutogen(dir.filePath("autogen.cfg"));
    fileAutogen.open(QIODevice::ReadOnly | QIODevice::Text);
    fileAutogen.copy(dir.filePath("autogen_backup.cfg")); // Create a copy of autogen.cfg
    fileAutogen.close();
    fileAutogen.open(QIODevice::WriteOnly | QIODevice::Text); // For write in the original
    QTextStream out(&fileAutogen);
    QFile fileBackup(dir.filePath("autogen_backup.cfg"));
    fileBackup.open(QIODevice::ReadOnly | QIODevice::Text); //read the copy
    QTextStream copy(&fileBackup);

    // Edit the first line with the information
    line = copy.readLine();
    out << "// generated by tremulous, modify by QTremBinds 0.4, do not modify \n";

    // Edit the second line (It would be have written "unbindall")
    line = copy.readLine();
    out << line << endl;

    // Start to write all the binds
    for(int i = 0; i < keys.count(); i++){ // See all the keys
        QString key = keys.at(i);
        Bind *bind = binds_.getBind(key);
        if(bind != NULL){
            QStringList actions = bind->getActions();
            QString acts = actions.join(";");
            QString newLine = "bind " + key + " " + '"' + acts + '"' + "\n";
            out << newLine;
            delete(bind);
        } // Else don't save and take the next key-bind
    }

    // Remove the old binds zone
    line = copy.readLine();
    while((!copy.atEnd()) && line.contains("bind")){
        line = copy.readLine();
    }

    // Edit the rest of the document
    out << line << endl;
    while(!copy.atEnd()){
        line = copy.readLine();
        out << line << endl;
    }

    // Close the files
    fileBackup.close();
    fileAutogen.close();
}


// Events handlers

void WidgetBinds::on_btnBack_clicked()
{
    if(m_ui->btnSave->isEnabled()){
        QMessageBox msgBox;
        msgBox.setText(tr("Binds have been modified"));
        msgBox.setInformativeText(tr("Do you want to save your changes?"));
        msgBox.setStandardButtons(QMessageBox::Discard | QMessageBox::Save | QMessageBox::Cancel);
        msgBox.setDefaultButton(QMessageBox::Cancel);
        msgBox.setIconPixmap(QPixmap(QString::fromUtf8(":/new/status/dialog-warning.png")));

        int ret = msgBox.exec();

        switch(ret){
        case QMessageBox::Discard:
            m_ui->btnSave->setEnabled(false);
            emit back();
            break;
        case QMessageBox::Save:
            m_ui->btnSave->setEnabled(false);
            saveBinds();
            emit back();
            break;
        case QMessageBox::Cancel: // Do nothing
            break;
        }
    }else
        emit back();
}

void WidgetBinds::on_comboKey_currentIndexChanged(QString key)
{
    // Update key button
    m_ui->btnKey->setText(m_ui->comboKey->currentText());

    // Update bind actions text
    m_ui->textBrowserInfoAdds->clear();
    m_ui->textBrowserInfoAdds->insertPlainText(tr("Key: "));
    m_ui->textBrowserInfoAdds->insertPlainText(key + "\n");
    m_ui->textBrowserInfoAdds->insertPlainText(tr("Actions: \n"));
    Bind bind;
    if(binds_.getBind(key) != NULL){
        bind.copy(binds_.getBind(key));
        QStringList actions = bind.getActions();
        QString acts = actions.join("\n");
        m_ui->textBrowserInfoAdds->insertPlainText(acts + "\n");
    }
}

void WidgetBinds::on_btnAddAction_clicked()
{
    // Get the action text to add
    QString actiontext;

    switch(currentAction_){
    case say: actiontext = m_ui->comboSay->currentText() + " " + m_ui->lineEditSayText->text();
        break;
    case sell: actiontext = m_ui->comboSell->currentText();
        break;
    case buy: actiontext = m_ui->comboBuy->currentText();
        break;
    case act: actiontext = m_ui->comboActiveItem->currentText();
        break;
    case evo: actiontext = m_ui->comboEvolution->currentText();
        break;
    case admin: actiontext = m_ui->comboAdmin->currentText();
        break;
    case mis: actiontext = m_ui->comboMis->currentText();
        break;
    }

    // Get the current bind
    Bind *bind = binds_.getBind(m_ui->comboKey->currentText());

    if(bind == NULL) // If the bind doesn't exist before, create it
        bind = new Bind(m_ui->comboKey->currentText());

    // Add the new action
    bind->addAction(actiontext);

    // Set the bind ind the list
    binds_.addBind(bind);

    // Show new action to the bind
    m_ui->textBrowserInfoAdds->insertPlainText(actiontext + "\n");

    // Now can save cause changes are made
    m_ui->btnSave->setEnabled(true);
}

void WidgetBinds::on_btnSave_clicked()
{
    m_ui->labSaveInfo->setText(tr("Saving..."));
    m_ui->btnSave->setEnabled(false);
    saveBinds();

    m_ui->labSaveInfo->setText(tr("Changes saved!"));

    this->startTimer(1500);
}

void WidgetBinds::on_btnReset_clicked()
{
    // delete the bind
    binds_.deleteBind(m_ui->comboKey->currentText());

    // Clear the text zone
    on_comboKey_currentIndexChanged(m_ui->comboKey->currentText());

    // Now can save
    m_ui->btnSave->setEnabled(true);
}

void WidgetBinds::timerEvent(QTimerEvent *event){
    m_ui->labSaveInfo->setText("");
    this->killTimer(event->timerId());
}

// Radio Buttons

void WidgetBinds::on_radioBtnSay_toggled(bool checked)
{
    if(checked){
        m_ui->comboSay->setEnabled(true);
        m_ui->lineEditSayText->setEnabled(true);
        m_ui->btnChooseColor->setEnabled(true);
        currentAction_ = say;
    }else{
        m_ui->comboSay->setEnabled(false);
        m_ui->lineEditSayText->setEnabled(false);
        m_ui->btnChooseColor->setEnabled(false);
    }
}


void WidgetBinds::on_radioBtnSell_toggled(bool checked)
{
    if(checked){
        m_ui->comboSell->setEnabled(true);
        currentAction_ = sell;
    }
    else
        m_ui->comboSell->setEnabled(false);
}

void WidgetBinds::on_radioBtnBuy_toggled(bool checked)
{
    if(checked){
        m_ui->comboBuy->setEnabled(true);
        currentAction_ = buy;
    }
    else
        m_ui->comboBuy->setEnabled(false);
}

void WidgetBinds::on_radioBtnActiveItem_toggled(bool checked)
{
    if(checked){
        m_ui->comboActiveItem->setEnabled(true);
        currentAction_ = act;
    }
    else
        m_ui->comboActiveItem->setEnabled(false);
}

void WidgetBinds::on_radioBtnEvolution_toggled(bool checked)
{
    if(checked){
        m_ui->comboEvolution->setEnabled(true);
        currentAction_ = evo;
    }
    else
        m_ui->comboEvolution->setEnabled(false);
}

void WidgetBinds::on_radioBtnAdmin_toggled(bool checked)
{
    if(checked){
        m_ui->comboAdmin->setEnabled(true);
        currentAction_ = admin;
    }
    else
        m_ui->comboAdmin->setEnabled(false);
}

void WidgetBinds::on_radioBtnMis_toggled(bool checked)
{
    if(checked){
        m_ui->comboMis->setEnabled(true);
        currentAction_ = mis;
    }
    else
        m_ui->comboMis->setEnabled(false);
}

void WidgetBinds::on_btnChooseColor_clicked()
{
    ColorDialog colorDialog(this);
    colorDialog.exec();

    if(colorDialog.result() == QDialog::Accepted){

        switch(colorDialog.getColor()){
        case Qt::red:
            m_ui->lineEditSayText->setText(m_ui->lineEditSayText->text() + "^1");
            break;

        case Qt::green:
            m_ui->lineEditSayText->setText(m_ui->lineEditSayText->text() + "^2");
            break;

        case Qt::yellow:
            m_ui->lineEditSayText->setText(m_ui->lineEditSayText->text() + "^3");
            break;

        case Qt::blue:
            m_ui->lineEditSayText->setText(m_ui->lineEditSayText->text() + "^4");
            break;

        case Qt::cyan:
            m_ui->lineEditSayText->setText(m_ui->lineEditSayText->text() + "^5");
            break;

        case Qt::magenta:
            m_ui->lineEditSayText->setText(m_ui->lineEditSayText->text() + "^6");
            break;

        case Qt::white:
            m_ui->lineEditSayText->setText(m_ui->lineEditSayText->text() + "^7");
            break;

        case Qt::black:
            m_ui->lineEditSayText->setText(m_ui->lineEditSayText->text() + "^8");
            break;
        }
    }

    m_ui->lineEditSayText->setFocus();
}

void WidgetBinds::on_btnKey_clicked()
{
    PressButtonDialog pressDialog;
    pressDialog.exec();

    QString key = pressDialog.getKey();
    int index = m_ui->comboKey->findText(key);

    if(index > -1){
        m_ui->comboKey->setCurrentIndex(index);
        m_ui->btnKey->setText(key);
    } // otherwise do nothing
}
